﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Arbore;
using Common;
using Satates;
using Operators;

namespace Algorithms.Depth
{
    public class DepthSearchAlgo:Algorithm
    {
        private bool switcher;
        private bool result = false;
        private Arbore.Arbore ab;

        public DepthSearchAlgo(State iState, List<State> fStates, List<iOperator> opr, List<string> log,
            ref Arbore.Arbore Ab) : base(iState, fStates, opr, log)
        {
            ab = Ab;
        }
		

        private bool expand(State thisState)
        {
        
            int counter = 0;
            if (switcher==true)
            {
                counter = getIndex(thisState.RedoOperator) ; switcher=false;
            }
            if (getIndex(thisState.CurrentOperator) == operatorNumber) { counter = 0; }
              Nod a = ab.CurrentNod;
            for (int i = counter; i <= operatorNumber; i++)
            {
                if (operators.ElementAt(i).available(thisState.CurrentState))
                {
                    var m=(Template) thisState.CurrentState.Clone();
                    State auxiliary = new State(operators.ElementAt(i).execute(m), operators.ElementAt(i));
                    ab.CurrentNod = a;
                    ab.AddS(new Nod(operators.ElementAt(i).ToString()+Environment.NewLine+auxiliary.ToString()));

                    if (!found(auxiliary))
                    {
                        btStack.Push(auxiliary); 
                        return true;
                    }
                }
            }
            return false;
        }

        private bool solve(State thisState)
        {

            if (switcher==true) switcher=false;
            if (thisState != null)
            {
                if (expand(thisState))
                {
                    if (solutionFound(btStack.Peek())) { result = true; return true; };
                }
                else
                {
                    iOperator auxiliaryOperator =(iOperator) btStack.Peek().CurrentOperator.Clone();
                    if (btStack.Count() > 1)
                        btStack.Pop();
                    State auxiliaryState = btStack.Peek();
                   // btStack.Pop();
                    auxiliaryState.RedoOperator=auxiliaryOperator;
                    btStack.Push(new State(auxiliaryState));
                    switcher=true;

                }
                solve(btStack.Peek());
            } return false;
        }
        public override bool solveProblem()
        {
            ab.AddS(new Nod(initialState.ToString()));
            solve(initialState);
            if (result == true) return true;
            return false;

        }
        public override void init()
        {
            switcher=false;
        }	
	}
    
}
